package com.zx.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import org.cyberneko.html.parsers.DOMParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class HttpImage {

    private static final Logger logger = LoggerFactory.getLogger(HttpImage.class);

    public static void main(String[] args) {
        byte[] b = getIconByUrl("http://www.runoob.com/html/html-tutorial.html");
        System.out.println(b.length);
    }

    /**
     * @param url
     * @return
     */
    public static byte[] getIconByUrl(String url) {
        try {
            //String url = "http://cn.ubuntu.com/?_ga=1.196693039.2025434214.1488983190";
            String host = null;
            String newUrl = null;
            if (url.startsWith("http://")) {
                host = url.substring(7);
                newUrl = "http://";
            } else if (url.startsWith("https://")) {
                host = url.substring(8);
                newUrl = "https://";
            }

            String[] split = host.split("/");

            String iconUrl = getIconUrl(url);

            //获得完整路径
            if (iconUrl != null && iconUrl.startsWith("http")) {
                byte[] b = getFileByUrl(iconUrl);
                return b;
                //获得cdn加速路径
            } else if (iconUrl != null && iconUrl.startsWith("//")) {
                byte[] b = getFileByUrl("http:" + iconUrl);
                return b;
            } else if (iconUrl != null && iconUrl.startsWith("/")) {

                for (int i = 0; i < split.length; i++) {
                    newUrl += split[i];
                    System.out.println(newUrl + iconUrl);
                    byte[] b = getFileByUrl(newUrl + iconUrl);
                    if (b != null) {
                        return b;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 获取一个连接
    private static HttpURLConnection getConnection(String urlString) throws IOException {
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setInstanceFollowRedirects(false);
        connection.setConnectTimeout(3000);
        connection.setReadTimeout(3000);
        connection
                .setRequestProperty("User-Agent",
                        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36");
        return connection;
    }

    /**
     * 获得icon在项目中的相对路径
     * 或，完整路径
     *
     * @param strUrl
     * @return
     * @throws Exception
     */
    public static String getIconUrl(String strUrl) throws Exception {
        // 生成html parser
        DOMParser parser = new DOMParser();

        HttpURLConnection conn = getConnection(strUrl);

        InputStream in = conn.getInputStream();

        parser.parse(new InputSource(in));
        Document doc = parser.getDocument();

        // 获得body节点，以此为根，计算其文本内容
        NodeList links = doc.getElementsByTagName("link");

        for (int i = 0; i < links.getLength(); i++) {
            Element link = (Element) links.item(i);
            String rel = link.getAttribute("rel");
            if ("shortcut icon".equalsIgnoreCase(rel)) {
                String icon = link.getAttribute("href");

                if (icon.startsWith("http")) {
                    return icon;
                }

                if (!icon.startsWith("/")) {
                    return "/" + icon;
                }

                return icon;
            }
        }
        return null;
    }

    /**
     * 根据地址获得数据的字节流
     *
     * @param strUrl 网络连接地址
     * @return
     */
    public static byte[] getFileByUrl(String strUrl) {

        URL url = null;
        HttpURLConnection conn = null;
        InputStream in = null;
        try {

            try {
                url = new URL(strUrl);
            } catch (MalformedURLException e) {
                logger.error("url：" + strUrl + "，格式异常");
                return null;
            }

            try {
                conn = (HttpURLConnection) url.openConnection();
            } catch (IOException e) {
                logger.error("url：" + strUrl + "，无法访问");
                return null;
            }

            try {
                conn.setRequestMethod("GET");
            } catch (ProtocolException e) {
                logger.error("url：" + strUrl + "，不支持使用get方法");
                return null;
            }

            try {
                conn.setConnectTimeout(5 * 1000);
            } catch (Exception e) {
                logger.error("url：" + strUrl + "，连接超时");
                return null;
            }

            try {
                in = conn.getInputStream();
            } catch (IOException e) {
                logger.error("url：" + strUrl + "，读取img异常");
                return null;
            }
            // 通过输入流获取图片数据
            byte[] b = readInputStream(in);// 得到图片的二进制数据
            return b;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                conn.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

    }

    /**
     * 从输入流中获取数据
     *
     * @param inStream 输入流
     * @return
     * @throws Exception
     */
    private static byte[] readInputStream(InputStream inStream) {
        ByteArrayOutputStream os = null;
        try {
            os = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            return os.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
